import json
from urllib.parse import urlencode, parse_qs
from urllib.request import urlopen

import logging
from rest_framework import status
from rest_framework.response import Response

from mall import settings

logger = logging.getLogger('meiduo')


class QQAuthonTool(object):
    def __init__(self):
        self.app_id = settings.QQ_APP_ID
        self.app_key = settings.QQ_APP_KEY
        self.redirect_uri = settings.QQ_REDIRECT_URL

    def get_openid_by_token(self, token):
        """
        根据token 获取 openid

        1.获取qq请求地址
        2.字典封装参数
        3.拼接地址 参数
        4.发送请求
        5.获取响应
        6.解析响应数据  获取openid
        :param token:
        :return:
        """

        # 1.获取qq请求地址
        base_url = "https://graph.qq.com/oauth2.0/me?"

        # 2.字典封装参数
        params = {
            "access_token": token
        }

        # 3.拼接地址 参数
        url = base_url + urlencode(params)

        try:
            # 4.发送请求
            resp = urlopen(url)
            # 5.获取响应
            data_str = resp.read().decode()

            # 6.解析响应数据  获取openid
            data_dict = json.loads(data_str[10:-4])

        except Exception as e:
            logger.error(e)
        else:
            if not data_dict:
                raise Exception('获取用户失败')

            return data_dict.get('openid',None)

    def get_token_by_code(self, code):
        # 2. 获取qq的请求地址
        base_url = "https://graph.qq.com/oauth2.0/token?"

        # 3. 使用字典拼接参数
        # PC网站：https://graph.qq.com/oauth2.0/token
        # GET
        # grant_type      必须      授权类型，在本步骤中，此值为“authorization_code”。
        # client_id       必须      申请QQ登录成功后，分配给网站的appid。
        # client_secret   必须      申请QQ登录成功后，分配给网站的appkey。
        # code            必须      上一步返回的authorization
        # redirect_uri    必须      与上面一步中传入的redirect_uri保持一致。
        params = {
            "grant_type": 'authorization_code',
            "client_id": self.app_id,
            "client_secret": self.app_key,
            "code": code,
            "redirect_uri": self.redirect_uri,
        }

        # 4. 拼接地址 参数
        req_url = base_url + urlencode(params)

        # 5. 发送请求
        response = urlopen(req_url)
        # 6. 获取数据 token
        # 获取响应数据
        data = response.read().decode()
        # 解析响应数据
        query_params = parse_qs(data)
        # access_token 字典
        access_token = query_params.get('access_token')
        # 校验数据
        if not access_token:
            raise Exception('获取token失败')

        return access_token[0]
